package com.brillilab.starter.controller.aio.lab;

import com.alibaba.fastjson.JSONObject;
import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.entity.PageVo;
import com.brillilab.common.entity.ResponseVo;
import com.brillilab.common.redis.RedisCache;
import com.brillilab.common.utils.ValidatorUtil;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.lab.LabJoinAuditStateEnum;
import com.brillilab.domain.enums.lab.LabMemberEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum;
import com.brillilab.domain.po.lab.LabJoinAudit;
import com.brillilab.domain.po.lab.LabMember;
import com.brillilab.domain.po.lab.LabMemberPower;
import com.brillilab.domain.po.system.Dict;
import com.brillilab.domain.po.user.Users;
import com.brillilab.domain.vo.lab.*;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.lab.ILabJoinAuditService;
import com.brillilab.service.core.lab.ILabMemberService;
import com.brillilab.service.core.message.IEventAuditService;
import com.brillilab.service.core.message.IMessageService;
import com.brillilab.service.core.system.IDictService;
import com.brillilab.service.logic.lab.LabMemberLogic;
import com.brillilab.service.logic.message.MessageLogic;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.service.module.message.producer.MessageProducer;
import com.brillilab.service.module.message.template.enums.MessageTypeEnum;
import com.brillilab.starter.aspect.AspectLog;
import com.brillilab.starter.constant.SelectorConstant;
import com.brillilab.starter.constant.StarterConstant;
import com.brillilab.starter.entity.resp.lab.EmpowerVerifyResp;
import com.brillilab.starter.handler.RequestPower;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 实验室成员API
 */
@RestController
@RequestMapping("/api/labMember")
public class LabMemberController {

    @Resource
    private ILabMemberService labMemberService;
    @Resource
    private LabMemberLogic labMemberLogic;
    @Resource
    private UsersLogic usersLogic;
    @Resource
    private MessageLogic messageLogic;
    @Resource
    private RedisCache redisCache;
    @Resource
    private IDictService dictService;
    
    /**
     * 分页获取实验室成员
     *
     * @param req
     * @return
     */
    @RequestMapping(value="/list", method=RequestMethod.POST)
    public ResponseVo getListLabId(@RequestBody LabMemberPageGet req, @RequestHeader(name=StarterConstant.TOKEN) String token) {

        Assert.isTrue(req.getState() != null,"请求参数缺失");

        Long labId=req.getLabId();
        if(!StringUtils.isBlank(token)){
            UserInfoVo userInfo=usersLogic.getUserByToken(token);
            labId=userInfo.getLabId();
        }

        //全部查找
        PageVo<LabMemberVo> page=labMemberService.selectPage(labId,req.getState(),1,99999);

        //手动分页排序
        labMemberLogic.lastStepSortResult(req,page,req.getPageNum(),req.getPageSize());

        return ResponseVo.success(page);
    }

    /**
     * 获取实验室所有成员登录后（包括权限等信息）
     *
     * @return
     */
    @RequestMapping(value="/list", method=RequestMethod.GET)
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo getAllLabMember(@RequestHeader(name=StarterConstant.TOKEN) String token) {

        if(StringUtils.isBlank(token)){
            return ResponseVo.failure(ResultEnum.REQUEST_PARAM_LACK);
        }

        UserInfoVo userInfoVo=usersLogic.getUserByToken(token);

        //查询所有
        List<LabMemberVo> result=labMemberService.selectList(userInfoVo.getLabId(),null);

        return ResponseVo.success(result);
    }

    /**
     * 根据权限获取开通/未开通的实验室成员列表 {\
     * "labId\":\"实验室ID必填L\",\"power\":\"权限必填S\",\"isOpen\":\"是否开通I:0-未开通，1-已开通I\"}
     *
     * @param json
     * @return
     */
    @PostMapping("/power")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo selectByPower(@RequestBody JSONObject json,@RequestHeader(name=StarterConstant.TOKEN) String token) {

        String power=json.getString("power");
        // Integer isOpen=json.getInteger("isOpen");
        Assert.isTrue(LabMemberPowerEnum.Power.getKey(power) != null && !StringUtils.isBlank(token) ,"请求参数缺失！");
        UserInfoVo userInfoVo=usersLogic.getUserByToken(token);

        Map<String, List<LabMemberVo>> resultMap=labMemberLogic.getPowerMemberListMap(power,userInfoVo);

        return ResponseVo.success(resultMap);
    }

    /**
     * 实验室成员移出/返回
     * {\"labMemberId\":\"实验室成员ID必填L\",\"state\":\"成员状态必填I:1-正常，2-移出\"}
     *
     * @return
     */
    @AspectLog
    @PostMapping("/state")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo updateState(@RequestBody JSONObject json,@RequestHeader(name=StarterConstant.TOKEN) String token) {
        Long labMemberId=json.getLong("labMemberId");
        Integer state=json.getInteger("state");
        if(labMemberId == null && StringUtils.isBlank(token)){
            return ResponseVo.failure(ResultEnum.REQUEST_PARAM_LACK);
        }
        if(LabMemberEnum.State.getKey(state) == null){
            return ResponseVo.failure(ResultEnum.REQUEST_PARAM_ERROR);
        }

        //移出，实验室owner不能被移出
        UserInfoVo userInfo=usersLogic.getUserByToken(token);
        Assert.isTrue(!userInfo.getLabMemberId().equals(labMemberId),"您无法对自己进行该项操作！");

        boolean b=labMemberLogic.outOrReturnLab(labMemberId,state,userInfo.getName());
        return b ? ResponseVo.success() : ResponseVo.failure();
    }

    /**
     * 发送短信授权码
     *
     * @return
     */
    @PostMapping("/empowerCode")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo sendEmpowerCode(@RequestBody JSONObject json,@RequestHeader(name=StarterConstant.TOKEN) String token) {

        String mobile=json.getString("mobile");
        Assert.isTrue(!StringUtils.isBlank(token),"请求参数缺失！");
        Assert.isTrue(ValidatorUtil.isPhone(mobile),"手机号格式错误");

        UserInfoVo userInfo=usersLogic.getUserByToken(token);

        //已是实验室成员不发送，返回错误信息
        Users user=usersLogic.getUser(mobile);
        if(user != null){
            LabMember labMember=labMemberService.selectMember(userInfo.getLabId(),user.getId());
            if(labMember != null && !LabMemberEnum.State.STATE_OUT.getValue().equals(labMember.getState())){
                ResponseVo failure=ResponseVo.failure("用户已经是实验室成员！");
                failure.setCode(1102);
                return failure;
            }
            ResponseVo failure=ResponseVo.failure("该用户已注册，是否加入当前实验室?");
            String certificateNo=user.getCertificateNo();
            if(StringUtils.isNotBlank(certificateNo) && certificateNo.length()>3) {
            	user.setCertificateNo(certificateNo.substring(0,3) + "*****" + certificateNo.substring(certificateNo.length()-3,certificateNo.length()));
            }
            failure.setData(user);
            failure.setCode(1101);
            return failure;
        }

        boolean b = messageLogic.sendEmpowerCode(mobile,userInfo.getLabId());
        return ResponseVo.success(null,"已发送成功，请提醒用户查收");
//        }
//        return ResponseVo.failure();
    }

    /**
     * 授权码校验 {\"labId\":\"实验室ID必填L\",\"code\":\"短信验证码S\"}
     *
     * @return
     */
    @PostMapping("/empowerVerify")
    public ResponseVo empowerVerify(@RequestBody JSONObject json) {
        Long labid=json.getLong("labId");
        String code=json.getString("code");
        Assert.isTrue(!StringUtils.isBlank(code) && labid != null,"请求参数缺失！");

        JSONObject jsonObj=(JSONObject) redisCache.getObj(StarterConstant.sms_empower_code + code.trim());
        if(jsonObj != null && jsonObj.get("labId") != null && jsonObj.get("mobile") != null){
            if(labid.equals(jsonObj.getLong("labId"))){
                EmpowerVerifyResp resp=new EmpowerVerifyResp();
                resp.setLabId(labid);
                String mobile=jsonObj.getString("mobile");
                resp.setMobile(mobile);
                // 判断用户是否存在
                Users user=usersLogic.getUser(mobile);
                if(user != null){
                    resp.setIsRegister(1);
                } else {
                    resp.setIsRegister(0);
                }
                redisCache.delete(StarterConstant.sms_empower_code + code.trim());
                return ResponseVo.success(resp);
            }
        }
        return ResponseVo.failure(ResultEnum.FAILURE,"授权码无效",null);
    }

    /**
     * 用户已存在，直接添加为实验室成员
     *
     * @param req
     * @return
     */
    @AspectLog
    @PostMapping("/add")
    public ResponseVo add(@RequestBody LabMemberAdd req,@RequestHeader(name="token") String token) {

        UserInfoVo userInfo=usersLogic.getUserByToken(token);

        Assert.isTrue(req != null && !StringUtils.isBlank(token) && req.getUserId() != null,"请求参数缺失！");
        Assert.isTrue(StringUtils.isNotBlank(req.getSmsCode()),"请输入验证码！");
        Assert.isTrue(StringUtils.isNotBlank(req.getDuty()),"请选择职称！");
        List<Dict> dictList=dictService.getDuty().stream().filter(d -> d.getName().equals(req.getDuty())).collect(Collectors.toList());
        Assert.isTrue(dictList!=null,"职称不存在！");

        LabMember labMemberExist=labMemberLogic.addLabMember(req,userInfo);
        return ResponseVo.success(labMemberExist);
    }


    /**
     * 获取成员下拉框
     * 有权限返回所有，无权限显示自己
     * @param power
     * @param token
     * @return
     */
    @GetMapping("/selector")
    public ResponseVo selector(String power,@RequestHeader(value=StarterConstant.TOKEN) String token){

        //校验参数
        Assert.isTrue(StringUtils.isNotBlank(power) && StringUtils.isNotBlank(token),"请求参数缺失！");
        UserInfoVo userInfo=usersLogic.getUserByToken(token);
        Assert.isTrue(userInfo.getLabId()!= null,"用户未加入实验室！");
        Assert.isTrue(userInfo.getLabMemberId()!=null,"用户不是实验室成员！");

        //查询
        List<LabMemberSelector> members=labMemberService.selectLabMemberSelectorList(userInfo.getLabId(),LabMemberEnum.State.STATE_IN.getValue());

        //过滤
        List<LabMemberPower> powers=userInfo.getPowers();
        if(!powers.stream().map(LabMemberPower::getPower).collect(Collectors.toList()).contains(power)){
            members = members.stream().filter(e -> e.getLabMemberId().equals(userInfo.getLabMemberId())).collect(Collectors.toList());
        }

        //结果
        LabMemberSelector nu = new LabMemberSelector();
        nu.setLabMemberId(SelectorConstant.NULL);
        nu.setUserName(SelectorConstant.PUBLIC);

        List<LabMemberSelector> rs = new LinkedList<>(members);
        ((LinkedList<LabMemberSelector>) rs).addFirst(nu);

        return ResponseVo.success(rs);
    }

    /**
     * 修改权限和小组
     * @param modify
     * @param token
     * @return
     */
    @AspectLog
    @RequestMapping(value="/entryModify",method=RequestMethod.PUT)
    public ResponseVo entryPowerAndTeamModify(@RequestBody PowerAndDutyModifyVo modify,@RequestHeader(value=StarterConstant.TOKEN) String token){

        Assert.isTrue(modify!=null && modify.getUserId()!=null,"请求参数缺失!");
        UserInfoVo userInfo=usersLogic.getUserByToken(token);
        usersLogic.entryPowerAndTeamModify(modify,userInfo);
        return ResponseVo.success();
    }

}
